package com.ebo.agora.openvcall.ui;

import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.PorterDuff;
import android.media.AudioManager;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewStub;
import android.view.WindowManager;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.ebo.agora.openvcall.AGApplication;
import com.ebo.agora.openvcall.model.AGEventHandler;
import com.ebo.agora.openvcall.model.ConstantApp;
import com.ebo.agora.propeller.Constant;
import com.ebo.agora.propeller.UserStatusData;
import com.ebo.agora.propeller.VideoInfoData;
import com.ebo.agora.propeller.ui.RtlLinearLayoutManager;
import com.ebo.apicloud.H5Activity;
import com.ebo.rongcloud.models.MyUser;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import http_utils.interfaces.IHttpPostListener;
import http_utils.utils.Ipost;
import http_utils.utils.URLs;
import io.agora.openvcall.R;
import io.agora.rtc.IRtcEngineEventHandler;
import io.agora.rtc.RtcEngine;
import io.agora.rtc.video.VideoCanvas;
import io.rong.imkit.RongIM;
import io.rong.imlib.RongIMClient;
import io.rong.imlib.model.UserInfo;
import utils.DensityUtil;
import utils.IToast;
import utils.Lg;

import static android.view.View.GONE;
import static android.view.View.VISIBLE;


public class ChatActivity extends BaseActivity implements AGEventHandler, RongIM.UserInfoProvider {

    private final static Logger log = LoggerFactory.getLogger(ChatActivity.class);

    private GridVideoViewContainer mGridVideoViewContainer;

    private RelativeLayout mSmallVideoViewDock;

    // should only be modified under UI thread
    private final HashMap<Integer, SurfaceView> mUidsList = new HashMap<>(); // uid = 0 || uid == EngineConfig.mUid

    private volatile boolean mVideoMuted = false;

    private volatile boolean mAudioMuted = false;

    private volatile int mAudioRouting = -1; // Default

    public static int cw, ch;
    static double ScreenInches;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //根据物理尺寸区分加载的布局
        ScreenInches = DensityUtil.getScreenInches(this);
        if (ScreenInches < 7) {
            //手机
            setContentView(R.layout.activity_chat);
        }
        else{
            //平板
            setContentView(R.layout.activity_chat_pad);
        }
        initViews();


//        Lg.d("ScreenInches = "+ScreenInches);
    }

    @Override
    protected void onResume() {
        super.onResume();
        DensityUtil.setHideVirtualKey(getWindow());
        DensityUtil.setHideVirtualKey(getWindow());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return false;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return false;
    }


    //LGY start
    public static String channel_Name, channel_name_code;
    int uid_Self;

    @Override
    protected void initUIandEvent() {

        if (event() == null) {
            synchronized (ChatActivity.class) {
                try {
//                    Lg.d("ccccccccccccccccccccccccccccccc!!!!!!!!!!!!!!!");
                    ((AGApplication) getApplication()).initWorkerThread();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        event().addEventHandler(this);
        WindowManager wm = this.getWindowManager();
        cw = wm.getDefaultDisplay().getWidth();
        ch = wm.getDefaultDisplay().getHeight();

        Intent i = getIntent();

        channel_Name = i.getStringExtra(ConstantApp.ACTION_KEY_CHANNEL_NAME);
        channel_name_code = i.getStringExtra(ConstantApp.KEY_CHANNEL_NAMECODE);
        String channelKey = i.getStringExtra(ConstantApp.KEY_CHANNEL_KEY);
        Lg.d("i.getIntExtra(ConstantApp.KEY_USER_ID, 0)=" + i.getIntExtra(ConstantApp.KEY_USER_ID, 0));
        uid_Self = i.getIntExtra(ConstantApp.KEY_USER_ID, 0);
        String app_id = i.getStringExtra(ConstantApp.KEY_APPID);
        final String encryptionKey = getIntent().getStringExtra(ConstantApp.ACTION_KEY_ENCRYPTION_KEY);
        final String encryptionMode = getIntent().getStringExtra(ConstantApp.ACTION_KEY_ENCRYPTION_MODE);

        doConfigEngine(encryptionKey, encryptionMode);

        mGridVideoViewContainer = (GridVideoViewContainer) findViewById(R.id.grid_video_view_container);
        mGridVideoViewContainer.setItemEventHandler(new VideoViewEventListener() {
            @Override
            public void onItemDoubleClick(View v, Object item) {

                log.debug("onItemDoubleClick " + v + " " + item + " " + mLayoutType);
                if (mUidsList.size() < 2) {
                    return;
                }
                UserStatusData user = (UserStatusData) item;
                int uid = (user.mUid == 0) ? config().mUid : user.mUid;

                if (mLayoutType == LAYOUT_TYPE_DEFAULT && mUidsList.size() != 1) {
                    switchToSmallVideoView(uid);
                } else {
                    switchToDefaultVideoView();
                }
            }
        });

        SurfaceView surfaceV = RtcEngine.CreateRendererView(getApplicationContext());
        rtcEngine().setupLocalVideo(new VideoCanvas(surfaceV, VideoCanvas.RENDER_MODE_HIDDEN, 0));
//        rtcEngine().setupLocalVideo(new VideoCanvas(surfaceV, VideoCanvas.RENDER_MODE_FIT, 0));
        surfaceV.setZOrderOnTop(false);
        surfaceV.setZOrderMediaOverlay(false);

        mUidsList.put(0, surfaceV); // get first surface view

        mGridVideoViewContainer.initViewContainer(getApplicationContext(), 0, mUidsList); // first is now full view
        worker().preview(true, surfaceV, 0);

        Log.d("aaaaaaaaaa", "channelKey =" + channelKey + ",channel_name_code=" + channel_name_code + ",uid_Self=" + uid_Self);
        worker().joinChannel(channelKey, channel_name_code, null, uid_Self);


        TextView textChannelName = (TextView) findViewById(R.id.channel_name);
        textChannelName.setText(channel_Name);

        optional();

//        LinearLayout bottomContainer = (LinearLayout) findViewById(R.id.bottom_container);
//        FrameLayout.MarginLayoutParams fmp = (FrameLayout.MarginLayoutParams) bottomContainer.getLayoutParams();
//        fmp.bottomMargin = virtualKeyHeight() + 16;

//        initMessageList();

        Lg.d("  RongIM.getInstance().getCurrentUserId()=" + RongIM.getInstance().getCurrentUserId());
        Lg.d("RongIM.getInstance().getCurrentConnectionStatus();=" + RongIM.getInstance().getCurrentConnectionStatus());
        String rong_uid = RongIM.getInstance().getCurrentUserId();
        boolean rong_IsConnection = RongIM.getInstance().getCurrentConnectionStatus().equals("CONNECTED");
        boolean needLogin = TextUtils.isEmpty(rong_uid) || !rong_IsConnection;
        if (!needLogin) {
            //融云账号已经登陆过则查找并加入群组
            send_FindGroupID(channel_Name);
        } else {
            //登陆融云账号
            send_Lgoin("" + uid_Self);
        }
        _loadWhiteBroad();
//        LoadingUtils.progressDialogDismiss();
//        Pub.loadWhiteBroad(webView,channel_name_code);
    }

    //LGY end
//    public void onClickHideIME(View view) {
//        log.debug("onClickHideIME " + view);
//        closeIME(findViewById(R.id.msg_content));
//
//        findViewById(R.id.msg_input_container).setVisibility(GONE);
//        findViewById(R.id.bottom_action_end_call).setVisibility(VISIBLE);
//        findViewById(R.id.bottom_action_container).setVisibility(VISIBLE);
//    }

//    private int mDataStreamId;


    private void optional() {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

        setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
    }

    private void optionalDestroy() {
    }

    private int getVideoProfileIndex() {
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        int profileIndex = pref.getInt(ConstantApp.PrefManager.PREF_PROPERTY_PROFILE_IDX, ConstantApp.DEFAULT_PROFILE_IDX);
        if (profileIndex > ConstantApp.VIDEO_PROFILES.length - 1) {
            profileIndex = ConstantApp.DEFAULT_PROFILE_IDX;

            // save the new value
            SharedPreferences.Editor editor = pref.edit();
            editor.putInt(ConstantApp.PrefManager.PREF_PROPERTY_PROFILE_IDX, profileIndex);
            editor.apply();
        }
        return profileIndex;
    }

    private void doConfigEngine(String encryptionKey, String encryptionMode) {
        int vProfile = ConstantApp.VIDEO_PROFILES[getVideoProfileIndex()];

        worker().configEngine(vProfile, encryptionKey, encryptionMode);
    }

    public void onBtn0Clicked(View view) {
        log.info("onBtn0Clicked " + view + " " + mVideoMuted + " " + mAudioMuted);
    }


    public void onCustomizedFunctionClicked(View view) {
        log.info("onCustomizedFunctionClicked " + view + " " + mVideoMuted + " " + mAudioMuted + " " + mAudioRouting);
        ImageView iv = (ImageView) view;
        if (mVideoMuted) {
            onSwitchSpeakerClicked();
            iv.setColorFilter(ContextCompat.getColor(this, R.color.agora_blue), PorterDuff.Mode.MULTIPLY);
        } else {
            onSwitchCameraClicked();
            iv.clearColorFilter();
        }

    }

    private void onSwitchCameraClicked() {
        RtcEngine rtcEngine = rtcEngine();
        rtcEngine.switchCamera();
    }

    private void onSwitchSpeakerClicked() {
        RtcEngine rtcEngine = rtcEngine();
        rtcEngine.setEnableSpeakerphone(mAudioRouting != 3);
    }

    @Override
    protected void deInitUIandEvent() {
        optionalDestroy();

        doLeaveChannel();
        event().removeEventHandler(this);

        mUidsList.clear();
    }

    private void doLeaveChannel() {
        worker().leaveChannel(config().mChannel);
        worker().preview(false, null, 0);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            onEndCallClicked(null);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    public void onEndCallClicked(View view) {
        log.info("onEndCallClicked " + view);
        Intent intent = new Intent();
        intent.setClass(this, H5Activity.class);
        intent.putExtra(H5Activity.KEY_OPEN_H5, true);
        //不传递startUrl的情况下，默认走自动加载widget的机制，即：APICloud引擎会自动去解析assets/widget目录下的资源并加载
        intent.putExtra("startUrl", "file:///android_asset/widget/html/monitor.html");
        startActivity(intent);
        finish();
    }

//    private VideoPreProcessing mVideoPreProcessing;
//    public void onBtnNClicked(View view) {
//        if (mVideoPreProcessing == null) {
//            mVideoPreProcessing = new VideoPreProcessing();
//        }
//
//        ImageView iv = (ImageView) view;
//        Object showing = view.getTag();
//        if (showing != null && (Boolean) showing) {
//            mVideoPreProcessing.enablePreProcessing(false);
//            iv.setTag(null);
//            iv.clearColorFilter();
//        } else {
//            mVideoPreProcessing.enablePreProcessing(true);
//            iv.setTag(true);
////            iv.setColorFilter(getResources().getColor(R.color.agora_blue), PorterDuff.Mode.MULTIPLY);
//            iv.setColorFilter(ContextCompat.getColor(this, R.color.agora_blue), PorterDuff.Mode.MULTIPLY);
//
//        }
//    }

    int sw, sh;
    RelativeLayout layout_smallvideo;

    //LGY start
    void initViews() {
        isCloseSmallVideo = true;
        WindowManager wm = this.getWindowManager();
        sw = wm.getDefaultDisplay().getWidth();
        sh = wm.getDefaultDisplay().getHeight();
        initWhiteBoard();
        if (MainActivity.IS_CloseSelfAudioAndVideo) {
            ImageView iv = (ImageView) findViewById(R.id.customized_function_id);
            iv.setVisibility(GONE);
            iv = (ImageView) findViewById(R.id.voice);
            iv.setVisibility(GONE);
            iv = (ImageView) findViewById(R.id.mute);
            iv.setVisibility(GONE);
        }
        layout_smallvideo = (RelativeLayout) findViewById(R.id.layout_smallvideo);



    }

    boolean has_loadwhiteboard;
    int w_whitebroad, h_whitebroad;

    void initWhiteBoard() {
//        if (layout_WhiteBroad == null) {
//            layout_WhiteBroad = (RelativeLayout) findViewById(layout_whiteboard);
//            layout_WhiteBroad.setVisibility(GONE);
//        }
        if (webView == null) {
            webView = (WebView) findViewById(R.id.wv_white);
            webView.setVisibility(VISIBLE);
        }
        has_loadwhiteboard = false;
        isfull_WhiteBroad = false;
//        w_whitebroad = layout_WhiteBroad.getLayoutParams().width;
//        h_whitebroad = layout_WhiteBroad.getLayoutParams().height;
        Lg.d("w_whitebroad=" + w_whitebroad + ",h_whitebroad=" + h_whitebroad);
//        loadWhiteBroad();

    }


    WebView webView;
//    RelativeLayout layout_WhiteBroad;

    //点击白板按钮，显示白板
//    public void onBtnWhiteBroadClicked(View view) {
//        _loadWhiteBroad();
//    }

    boolean isfull_WhiteBroad;

    private void _loadWhiteBroad() {
//        if(true){return;}
//        layout_WhiteBroad.setVisibility(VISIBLE);

        if (has_loadwhiteboard) {

            return;
        }
        has_loadwhiteboard = true;
        StringBuffer sb = new StringBuffer();
        sb.append(Constant.Whiteboard_Url);
        sb.append("key=");
        sb.append(ChatActivity.this.getString(R.string.private_app_id));
        sb.append("&cname=");
        sb.append(channel_name_code);
        sb.append("&role=");
        sb.append("guest");
        sb.append("&width=" + Constant.Whiteboard_W);
        sb.append("&height=" + Constant.Whiteboard_H);


        webView.getSettings().setUseWideViewPort(true);
        webView.getSettings().setLoadWithOverviewMode(true);
        webView.setWebViewClient(new WebViewClient() {
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                // 　　//handler.cancel(); 默认的处理方式，WebView变成空白页
                handler.proceed(); // 接受证书
                // handleMessage(Message msg); 其他处理
            }
        });
        // 这两行代码一定加上否则效果不会出现
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setDefaultTextEncodingName("gb2312");
        webView.loadUrl(sb.toString());

    }

    boolean isCloseSmallVideo = true;

    public void closeSmallVideo(View v) {
//        if (mSmallVideoViewDock == null) {
//            return;
//        }
        isCloseSmallVideo = !isCloseSmallVideo;
        ImageView iv = (ImageView) v;
        iv.setImageResource(isCloseSmallVideo ? R.drawable.close_smallvideo : R.drawable.open_smallvideo);
        if (isCloseSmallVideo) {
            layout_smallvideo.setVisibility(VISIBLE);
        } else {
            layout_smallvideo.setVisibility(View.INVISIBLE);
        }
    }

    //点击白班，隐藏白板
//    public void closeWebViewWhiteBoard(View v) {
//        layout_WhiteBroad.setVisibility(GONE);
//    }
    //LGY end

    public void onVoiceChatClicked(View view) {
        log.info("onVoiceChatClicked " + view + " " + mUidsList.size() + " video_status: " + mVideoMuted + " audio_status: " + mAudioMuted);
        if (mUidsList.size() == 0) {
            return;
        }

        SurfaceView surfaceV = getLocalView();
        ViewParent parent;
        if (surfaceV == null || (parent = surfaceV.getParent()) == null) {
            log.warn("onVoiceChatClicked " + view + " " + surfaceV);
            return;
        }

        RtcEngine rtcEngine = rtcEngine();
        mVideoMuted = !mVideoMuted;

        if (mVideoMuted) {
            rtcEngine.disableVideo();
        } else {
            rtcEngine.enableVideo();
        }

        ImageView iv = (ImageView) view;

//        iv.setImageResource(mVideoMuted ? R.drawable.btn_video : R.drawable.btn_voice);

        hideLocalView(mVideoMuted);

        if (mVideoMuted) {
            iv.setColorFilter(ContextCompat.getColor(this, R.color.agora_blue), PorterDuff.Mode.MULTIPLY);
            resetToVideoDisabledUI();
        } else {
            iv.setImageResource(R.drawable.btn_voice);
            iv.clearColorFilter();
            resetToVideoEnabledUI();
        }
    }

    private SurfaceView getLocalView() {
        for (HashMap.Entry<Integer, SurfaceView> entry : mUidsList.entrySet()) {
            if (entry.getKey() == 0 || entry.getKey() == config().mUid) {
                return entry.getValue();
            }
        }
        return null;
    }

    private void hideLocalView(boolean hide) {
        int uid = config().mUid;
        doHideTargetView(uid, hide);
    }

    private void doHideTargetView(int targetUid, boolean hide) {
        HashMap<Integer, Integer> status = new HashMap<>();
        status.put(targetUid, hide ? UserStatusData.VIDEO_MUTED : UserStatusData.DEFAULT_STATUS);
        if (mLayoutType == LAYOUT_TYPE_DEFAULT) {
            mGridVideoViewContainer.notifyUiChanged(mUidsList, targetUid, status, null);
        } else if (mLayoutType == LAYOUT_TYPE_SMALL) {
            UserStatusData bigBgUser = mGridVideoViewContainer.getItem(0);
            if (bigBgUser.mUid == targetUid) { // big background is target view
                mGridVideoViewContainer.notifyUiChanged(mUidsList, targetUid, status, null);
            } else { // find target view in small video view list
                log.warn("SmallVideoViewAdapter call notifyUiChanged " + mUidsList + " " + (bigBgUser.mUid & 0xFFFFFFFFL) + " target: " + (targetUid & 0xFFFFFFFFL) + "==" + targetUid + " " + status);
                mSmallVideoViewAdapter.notifyUiChanged(mUidsList, bigBgUser.mUid, status, null);
            }
        }
    }

    private void resetToVideoEnabledUI() {
        ImageView iv = (ImageView) findViewById(R.id.customized_function_id);
        iv.setImageResource(R.drawable.btn_switch_camera);
        iv.clearColorFilter();

        notifyHeadsetPlugged(mAudioRouting);
    }

    private void resetToVideoDisabledUI() {
        ImageView iv = (ImageView) findViewById(R.id.customized_function_id);
        iv.setImageResource(R.drawable.btn_speaker);
        iv.clearColorFilter();

        notifyHeadsetPlugged(mAudioRouting);
    }

    public void onVoiceMuteClicked(View view) {
        log.info("onVoiceMuteClicked " + view + " " + mUidsList.size() + " video_status: " + mVideoMuted + " audio_status: " + mAudioMuted);
        if (mUidsList.size() == 0) {
            return;
        }

        RtcEngine rtcEngine = rtcEngine();
        rtcEngine.muteLocalAudioStream(mAudioMuted = !mAudioMuted);

        ImageView iv = (ImageView) view;

        if (mAudioMuted) {
            iv.setColorFilter(ContextCompat.getColor(this, R.color.agora_blue), PorterDuff.Mode.MULTIPLY);
        } else {
            iv.clearColorFilter();
        }
    }

    @Override
    public void onFirstRemoteVideoDecoded(int uid, int width, int height, int elapsed) {
        doRenderRemoteUi(uid);
    }

    private void doRenderRemoteUi(final int uid) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isFinishing()) {
                    return;
                }

                if (mUidsList.containsKey(uid)) {
                    return;
                }

                SurfaceView surfaceV = RtcEngine.CreateRendererView(getApplicationContext());
                mUidsList.put(uid, surfaceV);

                boolean useDefaultLayout = mLayoutType == LAYOUT_TYPE_DEFAULT && mUidsList.size() != 2;

                surfaceV.setZOrderOnTop(!useDefaultLayout);
                surfaceV.setZOrderMediaOverlay(!useDefaultLayout);

                rtcEngine().setupRemoteVideo(new VideoCanvas(surfaceV, VideoCanvas.RENDER_MODE_HIDDEN, uid));

                if (useDefaultLayout) {
                    log.debug("doRenderRemoteUi LAYOUT_TYPE_DEFAULT " + (uid & 0xFFFFFFFFL));
                    switchToDefaultVideoView();
                } else {
                    int bigBgUid = mSmallVideoViewAdapter == null ? uid : mSmallVideoViewAdapter.getExceptedUid();
                    log.debug("doRenderRemoteUi LAYOUT_TYPE_SMALL " + (uid & 0xFFFFFFFFL) + " " + (bigBgUid & 0xFFFFFFFFL));
                    switchToSmallVideoView(bigBgUid);
                }
            }
        });
    }

    @Override
    public void onJoinChannelSuccess(String channel, final int uid, int elapsed) {
        log.debug("onJoinChannelSuccess " + channel + " " + (uid & 0xFFFFFFFFL) + " " + elapsed);

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isFinishing()) {
                    return;
                }

                SurfaceView local = mUidsList.remove(0);

                if (local == null) {
                    return;
                }
                if (MainActivity.IS_CloseSelfAudioAndVideo) {
                    if (uid == uid_Self) {
                        return;
                    }
                }
                mUidsList.put(uid, local);
            }
        });
    }

    @Override
    public void onUserOffline(int uid, int reason) {
        doRemoveRemoteUi(uid);
    }

    @Override
    public void onExtraCallback(final int type, final Object... data) {

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isFinishing()) {
                    return;
                }
                doHandleExtraCallback(type, data);
            }
        });
    }

    private void doHandleExtraCallback(int type, Object... data) {
        int peerUid;
        boolean muted;

        switch (type) {
            case AGEventHandler.EVENT_TYPE_ON_USER_AUDIO_MUTED:
                peerUid = (Integer) data[0];
                muted = (boolean) data[1];

                if (mLayoutType == LAYOUT_TYPE_DEFAULT) {
                    HashMap<Integer, Integer> status = new HashMap<>();
                    status.put(peerUid, muted ? UserStatusData.AUDIO_MUTED : UserStatusData.DEFAULT_STATUS);
                    mGridVideoViewContainer.notifyUiChanged(mUidsList, config().mUid, status, null);
                }

                break;

            case AGEventHandler.EVENT_TYPE_ON_USER_VIDEO_MUTED:
                peerUid = (Integer) data[0];
                muted = (boolean) data[1];
                doHideTargetView(peerUid, muted);
                break;

            case AGEventHandler.EVENT_TYPE_ON_USER_VIDEO_STATS:
                IRtcEngineEventHandler.RemoteVideoStats stats = (IRtcEngineEventHandler.RemoteVideoStats) data[0];

                if (Constant.SHOW_VIDEO_INFO) {
                    if (mLayoutType == LAYOUT_TYPE_DEFAULT) {
                        mGridVideoViewContainer.addVideoInfo(stats.uid, new VideoInfoData(stats.width, stats.height, stats.delay, stats.receivedFrameRate, stats.receivedBitrate));
                        int uid = config().mUid;
                        int profileIndex = getVideoProfileIndex();
                        String resolution = getResources().getStringArray(R.array.string_array_resolutions)[profileIndex];
                        String fps = getResources().getStringArray(R.array.string_array_frame_rate)[profileIndex];
                        String bitrate = getResources().getStringArray(R.array.string_array_bit_rate)[profileIndex];

                        String[] rwh = resolution.split("x");
                        int width = Integer.valueOf(rwh[0]);
                        int height = Integer.valueOf(rwh[1]);

                        mGridVideoViewContainer.addVideoInfo(uid, new VideoInfoData(height,
                                width, 0, Integer.valueOf(fps), Integer.valueOf(bitrate)));
                    }
                } else {
                    mGridVideoViewContainer.cleanVideoInfo();
                }

                break;

            case AGEventHandler.EVENT_TYPE_ON_SPEAKER_STATS:
                IRtcEngineEventHandler.AudioVolumeInfo[] infos = (IRtcEngineEventHandler.AudioVolumeInfo[]) data[0];

                if (infos.length == 1 && infos[0].uid == 0) { // local guy, ignore it
                    break;
                }

                if (mLayoutType == LAYOUT_TYPE_DEFAULT) {
                    HashMap<Integer, Integer> volume = new HashMap<>();

                    for (IRtcEngineEventHandler.AudioVolumeInfo each : infos) {
                        peerUid = each.uid;
                        int peerVolume = each.volume;

                        if (peerUid == 0) {
                            continue;
                        }
                        volume.put(peerUid, peerVolume);
                    }
                    mGridVideoViewContainer.notifyUiChanged(mUidsList, config().mUid, null, volume);
                }

                break;

            case AGEventHandler.EVENT_TYPE_ON_APP_ERROR:
                int subType = (int) data[0];

                if (subType == ConstantApp.AppError.NO_NETWORK_CONNECTION) {
                    showLongToast(getString(R.string.msg_no_network_connection));
                }

                break;

            case AGEventHandler.EVENT_TYPE_ON_DATA_CHANNEL_MSG:
                peerUid = (Integer) data[0];
                final byte[] content = (byte[]) data[1];
//                notifyMessageChanged(new Message(new User(peerUid, String.valueOf(peerUid)), new String(content)));
                break;
            case AGEventHandler.EVENT_TYPE_ON_AGORA_MEDIA_ERROR: {
                int error = (int) data[0];
                String description = (String) data[1];
//                notifyMessageChanged(new Message(new User(0, null), error + " " + description));
                break;
            }

            case AGEventHandler.EVENT_TYPE_ON_AUDIO_ROUTE_CHANGED:
                notifyHeadsetPlugged((int) data[0]);

                break;

        }
    }

    private void requestRemoteStreamType(final int currentHostCount) {
        log.debug("requestRemoteStreamType " + currentHostCount);
    }

    private void doRemoveRemoteUi(final int uid) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isFinishing()) {
                    return;
                }

                Object target = mUidsList.remove(uid);
                if (target == null) {
                    return;
                }

                int bigBgUid = -1;
                if (mSmallVideoViewAdapter != null) {
                    bigBgUid = mSmallVideoViewAdapter.getExceptedUid();
                }

                log.debug("doRemoveRemoteUi " + (uid & 0xFFFFFFFFL) + " " + (bigBgUid & 0xFFFFFFFFL) + " " + mLayoutType);

                if (mLayoutType == LAYOUT_TYPE_DEFAULT || uid == bigBgUid) {
                    switchToDefaultVideoView();
                } else {
                    switchToSmallVideoView(bigBgUid);
                }
            }
        });
    }

    private SmallVideoViewAdapter mSmallVideoViewAdapter;

    private void switchToDefaultVideoView() {
        if (mSmallVideoViewDock != null) {
            mSmallVideoViewDock.setVisibility(GONE);
        }
        mGridVideoViewContainer.initViewContainer(getApplicationContext(), config().mUid, mUidsList);

        mLayoutType = LAYOUT_TYPE_DEFAULT;
    }

    private void switchToSmallVideoView(int bigBgUid) {
        HashMap<Integer, SurfaceView> slice = new HashMap<>(1);
        slice.put(bigBgUid, mUidsList.get(bigBgUid));
        mGridVideoViewContainer.initViewContainer(getApplicationContext(), bigBgUid, slice);

        bindToSmallVideoView(bigBgUid);

        mLayoutType = LAYOUT_TYPE_SMALL;

        requestRemoteStreamType(mUidsList.size());
    }

    public int mLayoutType = LAYOUT_TYPE_DEFAULT;

    public static final int LAYOUT_TYPE_DEFAULT = 0;

    public static final int LAYOUT_TYPE_SMALL = 1;

    private void bindToSmallVideoView(int exceptUid) {
        if (mSmallVideoViewDock == null) {
            ViewStub stub = (ViewStub) findViewById(R.id.small_video_view_dock);

            mSmallVideoViewDock = (RelativeLayout) stub.inflate();
        }

        boolean twoWayVideoCall = mUidsList.size() == 2;

        RecyclerView recycler = (RecyclerView) findViewById(R.id.small_video_view_container);

        boolean create = false;

        if (mSmallVideoViewAdapter == null) {
            create = true;
            mSmallVideoViewAdapter = new SmallVideoViewAdapter(this, config().mUid, exceptUid, mUidsList, new VideoViewEventListener() {
                @Override
                public void onItemDoubleClick(View v, Object item) {
                    switchToDefaultVideoView();
                }
            });
            mSmallVideoViewAdapter.setHasStableIds(true);
        }
        recycler.setHasFixedSize(true);

        log.debug("bindToSmallVideoView " + twoWayVideoCall + " " + (exceptUid & 0xFFFFFFFFL));

        if (twoWayVideoCall) {
            recycler.setLayoutManager(new RtlLinearLayoutManager(this, RtlLinearLayoutManager.HORIZONTAL, false));
        } else {
            recycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        }
        recycler.addItemDecoration(new SmallVideoViewDecoration());
        recycler.setAdapter(mSmallVideoViewAdapter);

        recycler.setDrawingCacheEnabled(true);
        recycler.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_AUTO);

        if (!create) {
            mSmallVideoViewAdapter.setLocalUid(config().mUid);
            mSmallVideoViewAdapter.notifyUiChanged(mUidsList, exceptUid, null, null);
        }
        recycler.setVisibility(VISIBLE);
        mSmallVideoViewDock.setVisibility(VISIBLE);
    }

    public void notifyHeadsetPlugged(final int routing) {
        log.info("notifyHeadsetPlugged " + routing + " " + mVideoMuted);

        mAudioRouting = routing;

        if (!mVideoMuted) {
            return;
        }

        ImageView iv = (ImageView) findViewById(R.id.customized_function_id);
        if (mAudioRouting == 3) { // Speakerphone
            iv.setColorFilter(ContextCompat.getColor(this, R.color.agora_blue), PorterDuff.Mode.MULTIPLY);
//            iv.setColorFilter(getResources().getColor(R.color.agora_blue), PorterDuff.Mode.MULTIPLY);
        } else {
            iv.clearColorFilter();
        }

    }


    //融云 start===============================================================================

    /**
     * <p>连接服务器，在整个应用程序全局，只需要调用一次，需在 {@link #/init(Context)} 之后调用。</p>
     * <p>如果调用此接口遇到连接失败，SDK 会自动启动重连机制进行最多10次重连，分别是1, 2, 4, 8, 16, 32, 64, 128, 256, 512秒后。
     * 在这之后如果仍没有连接成功，还会在当检测到设备网络状态变化时再次进行重连。</p>
     *
     * @param token     从服务端获取的用户身份令牌（Token）。
     * @param /callback 连接回调。
     * @return RongIM  客户端核心类的实例。
     */
    private void connect(String token) {

        if (getApplicationInfo().packageName.equals(AGApplication.getCurProcessName(getApplicationContext()))) {
            RongIM.connect(token, new RongIMClient.ConnectCallback() {
                /**
                 * Token 错误。可以从下面两点检查 1.  Token 是否过期，如果过期您需要向 App Server 重新请求一个新的 Token
                 *                  2.  token 对应的 appKey 和工程里设置的 appKey 是否一致
                 */
                @Override
                public void onTokenIncorrect() {
                    IToast.show("融云tokne错误");
                }

                /**
                 * 连接融云成功
                 * @param userid 当前 token 对应的用户 id
                 */
                @Override
                public void onSuccess(String userid) {
                    initUserInfo();

                    rongcloud_LoginSuccess = true;
                    if (RongIM.getInstance() != null) {
//                        IToast.show("融云账号登陆成功！！！！！！！！");
                        //查找并加入融云群组
                        send_FindGroupID(channel_Name);

                    }
                }

                /**
                 * 连接融云失败
                 * @param errorCode 错误码，可到官网 查看错误码对应的注释
                 */
                @Override
                public void onError(RongIMClient.ErrorCode errorCode) {
//                    IToast.show("融云账号登陆失败！！！！！！！！");
//                    btn_Login.setText("登陆失败，errorCode=" + errorCode);
                }
            });
        }
    }

    String userId, token, nickname, rongyun_portrait_uri;
    boolean rongcloud_LoginSuccess, rongcloud_IntoGroupSuccess;

    //登陆，获取token
    void send_Lgoin(String uid) {
        Map<String, Object> postParams = new HashMap<String, Object>();
        postParams.put("uid", uid);
        Lg.d("uid=" + uid);
        Ipost.send(this, URLs.RONG_GETTOKEN, postParams, new PostGetToken(), false);
    }


    class PostGetToken implements IHttpPostListener {
        @Override
        public void responseSuccess(String result) {
            if (Ipost.isTimeOut(ChatActivity.this, result)) {
                return;
            }
            if (null != result) {
                Lg.d("result=" + result);
                try {
                    JSONObject resultObject = new JSONObject(result);
                    int error = resultObject.getInt("error");
                    //code200(200为正常)",
                    int code = resultObject.getInt("code");
                    switch (code) {
                        //成功
                        case 200:
                            userId = resultObject.getString("userId");
                            token = resultObject.getString("token");
                            nickname = resultObject.getString("nickname");
                            rongyun_portrait_uri = resultObject.getString("rongyun_portrait_uri");
                            connect(token);
                            break;
                        //其他失败文字提示
                        default:
                            IToast.show("登陆获取token失败");
                            break;
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    IToast.show("网络异常：\n" + e.toString());
                }
            }
        }
    }

    private static List<MyUser> userIdList;

    private void initUserInfo() {
        userIdList = new ArrayList<MyUser>();
        userIdList.add(new MyUser(userId, nickname, rongyun_portrait_uri));
        RongIM.setUserInfoProvider(this, true);

        if (RongIM.getInstance() != null) {
            Lg.d("initUserInfo success! userId=" + userId + ", nickname=" + nickname + " ,rongyun_portrait_uri=" + rongyun_portrait_uri);
            RongIM.getInstance().setCurrentUserInfo(new UserInfo(userId, nickname, Uri.parse(rongyun_portrait_uri)));
            RongIM.getInstance().setMessageAttachedUserInfo(true);
        } else {
            Lg.d("initUserInfo error");
        }
    }

    @Override
    public UserInfo getUserInfo(String s) {
        if (userIdList == null) {
            return null;
        }
        for (MyUser i : userIdList) {
            if (i.getUserId().equals(s)) {
//                Log.e(TAG, i.getPortraitUri());
                return new UserInfo(i.getUserId(), i.getName(), Uri.parse(i.getPortraitUri()));
            }
        }
        Log.e("MainActivity", "UserId is : " + s);
        return null;
    }

    //加入群组
    void send_JoinGroup(String group_id, String uid) {
        Map<String, Object> postParams = new HashMap<String, Object>();
        postParams.put("uid", uid);
        postParams.put("group_id", group_id);
        Lg.d("send_JoinGroup uid=" + uid + ",group_id=" + group_id);
        Ipost.send(this, URLs.GET_JOINGROUP, postParams, new PostJoinGroup(), false);
    }

    String rongcloud_GroupID;

    class PostJoinGroup implements IHttpPostListener {
        @Override
        public void responseSuccess(String result) {
            if (Ipost.isTimeOut(ChatActivity.this, result)) {
                return;
            }
            if (null != result) {
                Lg.d("PostJoinGroup result=" + result);
                try {
                    JSONObject resultObject = new JSONObject(result);
                    int error = resultObject.getInt("error");
                    //code200(200为正常)",
//                    int code = resultObject.getInt("code");
                    switch (error) {
                        //成功
                        case 0:
//                            IToast.show("融云群组加入成功！！！！！！！！");
//                            rongcloud_GroupID = resultObject.getString("group_id");
                            rongcloud_IntoGroupSuccess = true;
                            break;
                        //其他失败文字提示
                        default:
                            break;
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    IToast.show("网络异常：\n" + e.toString());
                }
            }
        }
    }

    //查找群组
    void send_FindGroupID(String room_name) {
        if (skipFindGroupID) {
            send_JoinGroup("12", "" + uid_Self);
            return;
        }
        Map<String, Object> postParams = new HashMap<String, Object>();
        postParams.put("room_name", room_name);
        Ipost.send(this, URLs.GET_FIND_GROUP_ID, postParams, new PostFindGroupID(), false);
    }


    class PostFindGroupID implements IHttpPostListener {
        @Override
        public void responseSuccess(String result) {
            if (Ipost.isTimeOut(ChatActivity.this, result)) {
                return;
            }
            if (null != result) {
                Lg.d("result=" + result);
                try {
                    JSONObject resultObject = new JSONObject(result);
                    int error = resultObject.getInt("error");
                    //code200(200为正常)",
//                    int code = resultObject.getInt("code");
                    switch (error) {
                        //成功
                        case 0:
//                            IToast.show("融云群组查找成功！！！！！！！！");
                            rongcloud_GroupID = resultObject.getString("group_id");
                            send_JoinGroup(rongcloud_GroupID, "" + uid_Self);
                            break;
                        //其他失败文字提示
                        default:
                            break;
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    IToast.show("网络异常：\n" + e.toString());
                }
            }
        }
    }

    boolean skipFindGroupID = true;


    public void onRongCloudClicked(View view) {
        if (!rongcloud_IntoGroupSuccess) {
            IToast.show("聊天账号正在登陆中……");
            return;
        }
//        Lg.d("  RongIM.getInstance().getCurrentUserId()=" + RongIM.getInstance().getCurrentUserId());
//        Lg.d("RongIM.getInstance().getCurrentConnectionStatus();=" + RongIM.getInstance().getCurrentConnectionStatus());
        if (RongIM.getInstance() != null) {
            RongIM.getInstance().startGroupChat(ChatActivity.this, skipFindGroupID ? "12" : rongcloud_GroupID, "群组聊天");
        } else {
            Lg.d("RongIM.getInstance()==null");
        }

//        RongIM.getInstance().startGroupChat(ChatActivity.this, "12", "群组聊天";channel_Name);
    }
    //融云 end================================================================================


}
